package com.Webserver.http;

import com.Webserver.core.EmptyRequestException;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;


public class HttpRequest {
    private String charsetName = "UTF-8";

    private String method;
    private String uri;
    private String protocol;

    private String requestURI;
    private String queryString;

    private Map<String, String> parameters = new HashMap<>();

    private Map<String, String> headers = new HashMap<>();

    private Socket socket;
    private byte[] contentData;

    public HttpRequest(Socket socket) throws IOException, EmptyRequestException {
        this.socket = socket;
        parseRequestLine();
        parseHeaders();
        parseContent();
    }

    private void parseRequestLine() throws IOException, EmptyRequestException {
        String len = readLine();
        if (len.isEmpty()) {
            throw new EmptyRequestException();
        }
        System.out.println(len);

        String[] str = len.split("\\s");
        method = str[0];
        uri = str[1];
        protocol = str[2];
        parseUri();

        System.out.println("method:" + method);
        System.out.println("uri:" + uri);
        System.out.println("protocol:" + protocol);
    }

    private void parseUri() {
        String[] data = uri.split("\\?");
        requestURI = data[0];
        if (data.length > 1) {
            queryString = data[1];
            parseParameter(queryString);
        }
        System.out.println("requestURI:" + requestURI);
        System.out.println("queryString:" + queryString);
    }

    public void parseParameter(String line){
        String[] paras = line.split("&");
        for (String para : paras) {
            String[] arr = para.split("=");
            if (arr.length > 1) {
                parameters.put(arr[0], arr[1]);
            } else {
                parameters.put(arr[0], null);
            }
        }
        System.out.println("parameters:" + parameters);
    }


    private void parseHeaders() throws IOException {
        while (true) {
            String len = readLine();
            if (len.isEmpty()) {
                break;
            }
            System.out.println("消息头:" + len);
            String[] data = len.split(":\\s");
            headers.put(data[0].toLowerCase(), data[1]);
        }
        System.out.println("headers:" + headers);
    }


    private void parseContent() throws IOException {
        if ("post".equalsIgnoreCase(method)) {
            if (headers.containsKey("content-length")) {
                int length = Integer.parseInt(headers.get("content-length"));
                InputStream in = socket.getInputStream();
                contentData = new byte[length];
                in.read(contentData);

                String type = headers.get("content-Type");
                if("application/x-www-form-urlencoded".equals(type)){
                    String line = new String(contentData);
                    System.out.println("正文内容:"+line);
                    parseParameter(line);
                }
            }
        }
    }

    private String readLine() throws IOException {
        InputStream is = socket.getInputStream();
        int d;
        StringBuilder builder = new StringBuilder();
        char pre = 'a', cur = 'a';
        while ((d = is.read()) != -1) {
            cur = (char) d;
            if (pre == 13 && cur == 10) {
                break;
            }
            builder.append(cur);
            pre = cur;
        }
        return builder.toString().trim();
    }

    public String getMethod() {
        return method;
    }

    public String getUri() {
        return uri;
    }

    public String getProtocol() {
        return protocol;
    }

    public String getHeader(String name) {
        return headers.get(name);
    }

    public String getRequestURI() {
        return requestURI;
    }

    public String getQueryString() {
        return queryString;
    }

    public String getParameter(String name) {
        String value = parameters.get(name);
        if(value!=null){
            try {
                value = URLDecoder.decode(value,charsetName);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return value;
    }

    private void setCharsetEncoding(String charsetName){
        this.charsetName=charsetName;

    }
}
